package site.jlopen.kuscia.service.node;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.secretflow.v1alpha1.common.Common.Status;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.BatchQueryDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.BatchQueryDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.BatchQueryDomainResponseData;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.CreateDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.DeployTokenStatus;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.Domain;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.NodeStatus;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.QueryDomainRequest;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.QueryDomainResponse;
import org.secretflow.v1alpha1.kusciaapi.DomainOuterClass.QueryDomainResponseData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

import site.jlopen.kuscia.cons.DomainConstants;
import site.jlopen.kuscia.entity.GrpcApiInfo;
import site.jlopen.kuscia.model.NodeVo;
import site.jlopen.kuscia.properties.KusciaAPIProperties;
import site.jlopen.kuscia.rpc.impl.KusciaDomainRpcImpl;

@Service
public class KusciaNodeManager extends AbstractNodeManager {
	private static Logger logger = LoggerFactory.getLogger(KusciaNodeManager.class);

	@Override
	public boolean createNode(GrpcApiInfo apiInfo, String domainId, String masterDomainId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		DomainOuterClass.CreateDomainRequest request = DomainOuterClass.CreateDomainRequest.newBuilder()
				.setDomainId(domainId)
				.setMasterDomainId(masterDomainId)
                .setAuthCenter(
                        DomainOuterClass.AuthCenter.newBuilder().setAuthenticationType("Token").setTokenGenMethod("UID-RSA-GEN").build())
                .build();
		try {
			CreateDomainResponse response = new KusciaDomainRpcImpl(apiProperties).createDomain(request);
			logger.info("创建节点结果：{}", response);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
		}
		return false;
	}

	@Override
	public void updateNode(GrpcApiInfo apiInfo) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		DomainOuterClass.UpdateDomainRequest request = DomainOuterClass.UpdateDomainRequest.newBuilder()
				.build();
		try {
			new KusciaDomainRpcImpl(apiProperties).updateDomain(request);
		} catch (Exception e) {
			logger.error("异常:{}", e);
		}
	}

	@Override
	public void deleteNode(GrpcApiInfo apiInfo, String domainId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		DomainOuterClass.DeleteDomainRequest request = DomainOuterClass.DeleteDomainRequest.newBuilder()
				.setDomainId(domainId)
				.build();
		try {
			DomainOuterClass.DeleteDomainResponse response = new KusciaDomainRpcImpl(apiProperties).deleteDomain(request);
			logger.info("{}", response);
		} catch (Exception e) {
			logger.error("异常:{}", e);
		}
	}

	@Override
	public NodeVo queryNode(GrpcApiInfo apiInfo, String domainId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		try {
			QueryDomainRequest request = QueryDomainRequest.newBuilder().setDomainId(domainId).build();
			QueryDomainResponse response = new KusciaDomainRpcImpl(apiProperties).queryDomain(request);
			logger.info("response:{}", response);
			QueryDomainResponseData data = response.getData();
			String cert = data.getCert();
			String domainId_ = data.getDomainId();
			String role = data.getRole();
			String masterDomainId = data.getMasterDomainId();
			if(StringUtils.isBlank(masterDomainId)) {
				return NodeVo.builder().domainId(domainId_).masterDomainId(masterDomainId).role(role).cert(cert)
						.status(DomainConstants.DomainEenableEnum.online.name()).build();
			}
			String deployToken = null;
			List<NodeStatus> statuss = data.getNodeStatusesList();

			String statusStr = DomainConstants.DomainEenableEnum.offline.name();
			if(null != statuss && statuss.size() > 0) {
				NodeStatus status = statuss.get(0);
				if (status.getStatus().equals(DomainConstants.DomainStatusEnum.Ready.name())) {
					statusStr = DomainConstants.DomainEenableEnum.online.name();
				}
			}else {
				List <DeployTokenStatus> tokenStatus = data.getDeployTokenStatusesList();
				if(null != tokenStatus && tokenStatus.size() > 0) {
					/*DeployTokenStatus tokenStatu = tokenStatus.get(0);
					if (tokenStatu.getState().equals(DomainConstants.TokenStatusEnum.unused.name())) {
						statusStr = DomainConstants.DomainEenableEnum.online.name();
					}*/
					for (DeployTokenStatus deployTokenStatus : tokenStatus) {
						if (deployTokenStatus.getState().equals(DomainConstants.TokenStatusEnum.unused.name())) {
							deployToken = deployTokenStatus.getToken();
						}
					}
				}
				
			}
			NodeVo vo = NodeVo.builder().domainId(domainId_).masterDomainId(masterDomainId).role(role).cert(cert)
					.status(statusStr).deployToken(deployToken).build();
			return vo;
		} catch (Exception e) {
			logger.error("获取节点{}信息异常:{}", domainId, e);
			return null;
		}
	}

	@Override
	public void batchQueryNode(GrpcApiInfo apiInfo, String domainId) {
		KusciaAPIProperties apiProperties = apiInfo.convert(apiInfo);
		List<String> ids = Lists.newArrayList(domainId);
		BatchQueryDomainRequest request = BatchQueryDomainRequest.newBuilder().addAllDomainIds(ids).build();
		try {
			BatchQueryDomainResponse response = new KusciaDomainRpcImpl(apiProperties).batchQueryDomain(request);
			BatchQueryDomainResponseData data = response.getData();
			List<Domain> domains = data.getDomainsList();
			for (Domain domain : domains) {
				String cert = domain.getCert();
				String domainId_ = domain.getDomainId();
				String role = domain.getRole();
				NodeVo vo = NodeVo.builder().domainId(domainId_).role(role).cert(cert).build();
			}
			System.out.println(domains);
		} catch (Exception e) {
			logger.error("获取节点{}信息异常:{}", domainId, e);
		}
	}

}
